﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using DemoModule.Views;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Unity;
using WPF60.DemoModule.Views.HelicopterIntro;
using WPF60.DemoModule.Views.LeftNav;
using WPF60.DemoModule.Views.SimpleViews;
using WPF60.Infrastructure.CabSupport;
using WPF60.Infrastructure.Events;
using WPF60.Infrastructure.Model;
using WPF60.Infrastructure.Services;

namespace WPF60.DemoModule
{
    public class DemoModule : IModule
    {
        private readonly IRegionManager _regionManager;
        private readonly IUnityContainer _container;

        public DemoModule(IRegionManager regionManager, IUnityContainer container)
        {
            _regionManager = regionManager;
            _container = container;
        }

        public void Initialize()
        {
            //all parts of the app will share this instance:
            _container.RegisterInstance(_container.Resolve<IEventAggregator>());

            HandlePageSelect();
            RegisterViews();
        }


        void HandlePageSelect()
        {
            _container.Resolve<IEventAggregator>()
                .GetEvent<PageSelectedEvent>()
                .Subscribe(obj => ReplaceView(obj), true);

        }



        private void RegisterViews()
        {

            //Left Nav
            _container.RegisterType<IDemoPageProvider, DemoPageProvider>();

            _container.RegisterType<ILeftNavView, LeftNavView>();
            _container.RegisterType<ILeftNavViewModel, LeftNavViewModel>();
            ReplaceView<LeftNavPresenter>(Regions.LeftNav);

            //Intro Animation
            _container.RegisterType<IMeetingTimeProvider, MeetingTimeProvider>();
            _container.RegisterType<ICoolWpfView, CoolWpf>();
            _container.RegisterType<ICoolIntroViewModel, CoolIntroViewModel>();

            ReplaceView(new DemoPage()
                {Name = "WPF in 60 Seconds", PresenterClassName = typeof(TitlePage).FullName});


        }


        void ReplaceView<T>(string regionName)
            where T : IPresenterBase
        {
            ReplaceView(regionName, typeof(T).FullName);
        }



        void ReplaceView(DemoPage page)
        {

            var presenter = _container.Resolve(Type.GetType(page.PresenterClassName));

            if (presenter is UserControl)
            {
                //put it inside a titleable inner region:

                var obj = ReplaceView(Regions.ShellMainRegion, typeof(SimpleViewHolder).FullName);
                
                var titleAble = obj as SimpleViewHolder;

                if (titleAble != null)
                {
                    titleAble.Title = page.Name;
                }

                //put the simple view page in the holder's main region:
                ReplaceView(Regions.MainRegion, page.PresenterClassName);

            }
            else
            {
                //put it in the main region
                var obj = ReplaceView(Regions.ShellMainRegion, page.PresenterClassName);
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="regionName"></param>
        /// <param name="typeName">can be IPresenterBase, UserControl
        /// If interface is used, it needs to be Registered in the container
        /// </param>
        object ReplaceView(string regionName, string typeName)
        {
            //remove previous view:
            var views = _regionManager.Regions[regionName].Views;
            if (views != null && views.Count() > 0)
            {
                var view = views.First();
                _regionManager.Regions[regionName].Remove(view);
            }

            var newViewObj = _container.Resolve(Type.GetType(typeName));

            var presenter = newViewObj as IPresenterBase;

            if (presenter != null)
            {
                _regionManager.Regions[regionName].Add(presenter.ViewObj);
                presenter.Setup();
            }

            var newView = newViewObj as UserControl;

            if (newView != null)
            {
                _regionManager.Regions[regionName].Add(newView);
            }

            return newViewObj;
        }

    }
}